package org.upo.eps.it.phama.struts.action;

import java.io.PrintWriter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;
import org.hibernate.HibernateException;
import org.upo.eps.it.phama.bean.Almacen;
import org.upo.eps.it.phama.bean.Producto;
import org.upo.eps.it.phama.bean.Proveedor;
import org.upo.eps.it.phama.dao.ProductoDAO;
import org.upo.eps.it.phama.struts.actionform.ProductosActionForm;

/**
 *
 * @author grupo 4
 */
public class ProductosAction extends org.apache.struts.action.Action {

    /**
     * This is the action called from the Struts framework.
     *
     * @param mapping The ActionMapping used to select this instance.
     * @param form The optional ActionForm bean for this request.
     * @param request The HTTP Request we are processing.
     * @param response The HTTP Response we are processing.
     * @throws java.lang.Exception
     * @return
     */
    @Override
    public ActionForward execute(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception {

        /* Los métodos execute de todos los Action efectúan la misma comprobación. Si la sesión
         * guarda un atributo User es porque hay un usuario identificado, por lo que se puede
         * continuar con la ejecución del método. Si no lo hay, se redirige al usuario a la página
         * de logado.
         */

        ProductosActionForm af = (ProductosActionForm) form;
        String opcion = af.getOpcion().toLowerCase();
        String result = "failure";
        switch (opcion) {
            case "menu":
                result = "menu";
                break;
            case "grabar":
                crear(af, response.getWriter());
                break;
            case "buscar":
                result = buscar(af, response.getWriter());
                break;
            case "eliminar":
                result = eliminar(af, response.getWriter());
                break;
            case "modificar":
                result = modificar(af, response.getWriter());
                break;

        }
        return mapping.findForward(result);
    }

//<editor-fold defaultstate="collapsed" desc="private methods">
    private String buscar(ProductosActionForm form, PrintWriter out) {
        /* Basicamente, se efectúa una búsqueda de todos los productos cuyos datos correspondan a los aportados por
         * el usuario en el formulario de búsqueda. Este resultado es asignado al atributo resultadoBusqueda del
         * ActionForm y después se recorre para construir una cadena JSON que se devolverá al cliente por medio
         * del objeto response.
         * Cualquier excepción también se devolverá de la misma forma.
         */
        String result = "failure";
        String coste = "";
        String precio = "";
        String almacen = "";
        String proveedor = "";

        if(form.getIdAlmacen()!=0){ almacen = String.valueOf(form.getIdAlmacen()); }
        if(form.getIdProveedor()!=0){ proveedor = String.valueOf(form.getIdProveedor()); }
        if (form.getCoste() > 0.0) { coste = String.valueOf(form.getCoste()); }
        if (form.getPrecio() > 0.0) { precio = String.valueOf(form.getPrecio()); }

        form.setResultadoBusqueda(ProductoDAO.search(form.getNombre(), coste, precio, almacen, proveedor));

        JSONArray jsonArray = new JSONArray();
        try {
            for (Producto pro : form.getResultadoBusqueda()) {
                JSONObject json = new JSONObject();
                json.put("id", pro.getIdProducto());
                json.put("nombre", pro.getNombre());
                json.put("descripcion", pro.getDescripcion());
                json.put("coste", pro.getCoste());
                json.put("precio", pro.getPrecio());
                json.put("iva", pro.getIva());
                json.put("nombreAlmacen", pro.getAlmacen() != null ? pro.getAlmacen().getFullname() : "");
                json.put("idAlmacen", pro.getAlmacen() != null ? pro.getAlmacen().getIdAlmacen() : "-1");
                json.put("nombreProveedor", pro.getProveedor() != null ? pro.getProveedor().getFullname() : "");
                json.put("idProveedor", pro.getProveedor() != null ? pro.getProveedor().getIdProveedor() : "-1");
                jsonArray.put(json);
            }
            out.print(jsonArray);
            result = "success";
        } catch (JSONException ex) {
            out.println("<div id='excepcion'>");
            out.println(String.format("<ul><li>Se ha producido el siguiente error: %s</li></ul>", ex.getMessage()));
            out.println("</div>");
        } finally {
            return result;
        }
    }

    private String crear(ProductosActionForm form, PrintWriter out) {
        /* La petición de creación de un producto pasa por hacerlo persistente en la base de datos. Para
         * ello es necesario obtener una referencia a los objetos Almacen y Proveedor, que son atributos
         * del producto.
         * Si se produce alguna excepción, se genera una cadena que se añade al objeto response para
         * el tratamiento por parte del cliente.
         */
        String result = "failure";
        try {
            Producto producto = new Producto(form.getNombre(), form.getDescripcion(), form.getCoste(), form.getPrecio(), form.getIva());

            Almacen almacen = new Almacen();
            almacen.setIdAlmacen(form.getIdAlmacen());
            producto.setAlmacen(almacen);

            Proveedor proveedor = new Proveedor();
            proveedor.setIdProveedor(form.getIdProveedor());
            producto.setProveedor(proveedor);

            ProductoDAO.save(producto);
            form.getMisProductos().add(producto);
            result = "success";
        } catch (HibernateException ex) {
            out.println("<div id='excepcion'>");
            out.println(String.format("<ul><li>Se ha producido el siguiente error: %s</li></ul>", ex.getMessage()));
            out.println("</div>");
        } finally {
            return result;
        }
    }

    private String eliminar(ProductosActionForm form, PrintWriter out) {
        /* Cuando se solicita eliminar un producto, se ejecuta el método correspondiente de la 
         * clase DAO. Cualquier excepción es devuelta como cadena mediante la respuesta HTTP.
         */
        String result = "failure";
        try {
            ProductoDAO.delete(form.getId());
            result = "success";
        } catch (HibernateException ex) {
            out.println("<div id='excepcion'>");
            out.println(String.format("<ul><li>Se ha producido el siguiente error: %s</li></ul>", ex.getCause()));
            out.println("</div>");
        } finally {
            return result;
        }
    }

    private String modificar(ProductosActionForm form, PrintWriter out) {
        /* Modificar un producto es similar a su creación
         */
        String result = "failure";
        try {
            Producto producto = new Producto(form.getNombre(), form.getDescripcion(), form.getCoste(), form.getPrecio(), form.getIva());
            producto.setIdProducto(form.getId());
            
            Almacen almacen = new Almacen();
            almacen.setIdAlmacen(form.getIdAlmacen());
            producto.setAlmacen(almacen);

            Proveedor proveedor = new Proveedor();
            proveedor.setIdProveedor(form.getIdProveedor());
            producto.setProveedor(proveedor);

            ProductoDAO.save(producto);
            form.getMisProductos().add(producto);
            result = "success";
        } catch (HibernateException ex) {
            out.println("<div id='excepcion'>");
            out.println(String.format("<ul><li>Se ha producido el siguiente error: %s</li></ul>", ex.getMessage()));
            out.println("</div>");
        } finally {
            return result;
        }
    }
    //</editor-fold>
}
